-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
467 feature request add dsts support #482
base: main
Are you sure you want to change the base?
Conversation
5517451
to
83ca36e
Compare
it's still in draft, but I would like some feedback @chlowell, if I'm taking this to the right direction. there's more than enough code already, I think I covered all the cases mentioned in the linked issue. |
localhost = "http://localhost" | ||
refresh = "fake_refresh" | ||
token = "fake_token" | ||
) | ||
|
||
var tokenScope = []string{"the_scope"} | ||
|
||
func fakeClient(tk accesstokens.TokenResponse, credential Credential, options ...Option) (Client, error) { | ||
client, err := New(fakeAuthority, fakeClientID, credential, options...) | ||
func fakeClient(tk accesstokens.TokenResponse, credential Credential, fAuthority string, options ...Option) (Client, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pls undo this name shortnening as it is harder to read the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expanded
err = c.Comm.JSONCall(ctx, endpoint, http.Header{}, qv, nil, &resp) | ||
} | ||
return resp, err | ||
} | ||
|
||
func (c Client) DSTSInstanceDiscovery(ctx context.Context, authorityInfo Info) (InstanceDiscoveryResponse, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very surprised to see this, was under the impression that dSTS doesn't support instance discovery.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, instance discovery is not supported.
"tenant can't be common for AAD": {authority: host + uuid1, tenant: "common", expectError: true}, | ||
"tenant can't be consumers for AAD": {authority: host + uuid1, tenant: "consumers", expectError: true}, | ||
"tenant can't be organizations for AAD": {authority: host + uuid1, tenant: "organizations", expectError: true}, | ||
"can't override tenant for ADFS ever": {authority: host + "adfs", tenant: uuid1, expectError: true}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test for ADFS where tenant is null / empty and where we expect to get back the original authority.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
The field isn't used anywhere. Removing it simplifies the work on introducing authority abstraction. We might re-add it once we need it for anything.
…ONCall Parsing the url, then setting qv.Encode() manually to u.RawQuery feel like an overcomplicated approach of creating url for http request. Use the native constructor, which enforces ctx to be passed into the request, and do simple sprintf for url + query.
This enables adding the same const for dSTS later in the process.
83ca36e
to
35a4182
Compare
@@ -23,7 +23,8 @@ import ( | |||
|
|||
const ( | |||
authorizationEndpoint = "https://%v/%v/oauth2/v2.0/authorize" | |||
instanceDiscoveryEndpoint = "https://%v/common/discovery/instance" | |||
aadInstanceDiscoveryEndpoint = "https://%v/common/discovery/instance" | |||
dstsInstanceDiscoveryEndpoint = "https://%v/dstsv2/common/discovery/instance" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
authorityType = ADFS | ||
case "dstsv2": | ||
if len(pathParts) != 3 { | ||
return Info{}, errors.New(`dSTS authority must be an https URL such as "https://<authority>/dstsv2/<your tenant>"`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hard-coded tenant + added validation
apps/internal/oauth/resolvers.go
Outdated
return fmt.Sprintf("https://%s/adfs/.well-known/openid-configuration", authorityInfo.Host), nil | ||
} else if authorityInfo.AuthorityType == authority.DSTS { | ||
resp, err := m.rest.Authority().DSTSInstanceDiscovery(ctx, authorityInfo) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to ADFS, you can use a hard coded URL for dSTS. An example of this endpoint on dSTS
IMPORTANT! To connect to this endpoint you need to be on our VPN.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hard-coded the url
host := "https://localhost/" | ||
for _, test := range []struct { | ||
|
||
tests := map[string]struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make sure to run this against real dSTS at least once.
The best way to do this is to create a sample project on the following repository
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test isn't actually firing any http requests, can you elaborate on what you mean by 'against real dSTS at least once'? I am not aware of any tests which I changed in the context of this PR are actually accessing anything e2e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean if you want me to manually validate that we can get a token from dSTS using this flow I can do that (I already did that a long time ago, but the set-up we used was deprecated by the recent dSTS crack-down on MS-corp based identities)
I guess that is why you are suggesting to 'build my own test dSTS' in C# and run it locally to test against? because at this point I can't see any easy way of how to call dSTS from SAW (I can hardly compile go there), so the only thing that comes to mind is some ev2 shell extension or something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend moving this discussion outside of GitHub. Happy to cut a preview release for testing purposes. Agree that we should have some sort of manual validation, at least of some scenarios (client_credentials flow probably. I think user flows are a bit broken right now anyway)
ExtExpiresOn: internalTime.DurationTime{T: time.Now().Add(1 * time.Hour)}, | ||
GrantedScopes: accesstokens.Scopes{Slice: tokenScope}, | ||
TokenType: "Bearer", | ||
}, cred, "https://fake_authority/dstsv2/fake_tenant") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
t.Errorf("unexpected access token %s", tk.AccessToken) | ||
} | ||
|
||
// fail for another tenant |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe there still is a value in checking that we will fail the execution in case anyone tries to do WithTenant on dSTS flow
case ADFS: | ||
return p, errors.New("ADFS authority doesn't support tenants") | ||
case DSTS: | ||
authority = "https://" + path.Join(p.AuthorityInfo.Host, "dstsv2", ID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed to always return an error if it hits this case
, there are only three possible cases on WithTenant
for dSTS flow that we care about
ID == ""
-> returns identicalAuthParams
ID == dSTS tenant
-> returns identicalAuthParams
- neither of the above -> should return error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🕐
This allows reusing the function for dSTS flow.
35a4182
to
5ee15d8
Compare
5ee15d8
to
99f29ff
Compare
Quality Gate passedIssues Measures |
No description provided.